﻿using System;
using System.Web;
using System.Web.UI;
using System.IO;
using System.Text.RegularExpressions;
using System.Collections.Generic;

namespace HelpersDotNet.HttpHandlers
{
    /// <example>
    ///     The following is an example of consuming Helpers.Net CSS Handler, in web.config
    ///    <code>
    ///         <configuration>
    ///             <system.webServer>
    ///                 <handlers>
    ///                 <add name="css" verb="GET" path="*.css" preCondition="integratedMode" type="HelpersDotNet.HttpHandlers.Css,Helpers.Net" />
    ///                 </handlers>
    ///             </system.webServer>
    ///         <configuration>
    ///    </code>
    /// </example>
    public class Css : IHttpHandler
    {
        #region IHttpHandler Members

        public bool IsReusable
        {
            get { return false; }
        }

        public void ProcessRequest(HttpContext context)
        {
            string path = context.Request.PhysicalPath;

            if (context.Request.QueryString != null && context.Request.QueryString.ToString().Length > 0)
            {
                path = context.Request.QueryString.ToString().Trim();
                path = context.Server.MapPath(path);
            }

            try
            {
                string css = this.ProcessCss(context, path);
                context.Response.ContentType = "text/css";
                context.Response.Write(css);
            }
            catch (FileNotFoundException ex)
            {
                string m = ex.Message.Replace(@"\", "/");
                m = m.Substring(m.LastIndexOf("/") + 1);
                context.Response.StatusCode = 0x194;
                context.Response.Write("File Not Found:" + m);
                throw;
            }
            catch (Exception ex)
            {
                context.Response.StatusCode = 500;
                context.Response.Write("Error: " + ex.Message);
            }
        }

        #endregion

        #region Helper Methods

        private List<string> filenames = new List<string>();

        private string ProcessCss(HttpContext context, string path)
        {
            if (!path.EndsWith(".css"))
                throw new Exception("File must be .css");
            if (!File.Exists(path))
                throw new FileNotFoundException(path);

            string css = context.Cache["csshandler-" + path] as string ?? "";

            if (string.IsNullOrEmpty(css))
            {
                using (StreamReader reader = new StreamReader(path))
                {
                    css = reader.ReadToEnd();
                    css = this.ProcessCssUrl(css);
                }

            }
            return css;
        }

        private string ProcessCssUrl(string css)
        {
            Regex regex = new Regex(@"url\s*\(\s*(?<url>~.*)\s*\)");
            for (Match match = regex.Match(css); match.Success; match = match.NextMatch())
            {
                string oldValue = match.Groups["url"].Value;
                css = css.Replace(oldValue, VirtualPathUtility.ToAbsolute(oldValue));
            }
            return css;
        }
        #endregion
    }
}
